package com.youcan.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.youcan.dao.BaseDao;
import com.youcan.util.GenericsUtils;

/**
 * @author LiChao E-mail:what_is_javascript@163.com
 * @date:2012-8-20 下午12:39:40
 * @version :V1.0
 * 
 */
@Component
public class BaseDaoImpl<T> implements BaseDao<T> {
	// 一个session对象
	Session se = null;
	private Class<T> persistentClass;

	@Autowired
	protected HibernateTemplate hibernateTemplate;

	public Class<T> getPersistentClass() {
		return persistentClass;
	}

	// Spring注入HibernateTemplate
	
//	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
//		this.hibernateTemplate = hibernateTemplate;
//	}

	// 初始化要操作的Entity Bean
	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		// 通过反射获取实体对象
		this.persistentClass = GenericsUtils
				.getSuperClassGenricType(getClass());
	}
	
	public List<T> findAll() {
		//通过实体类类型获取类名
		String className = persistentClass.getName();//java.lang.Object
		//TODO ..
		 StringBuffer sb = new StringBuffer();  
	        sb.append("from ");  
	        sb.append(className);  
	        List<T> list = (List<T>)hibernateTemplate.find(sb.toString());
		return list;
	}

	
	public T findById(String className,Serializable id) {
		try {
			return (T) hibernateTemplate.load(Class.forName(className), id);
		} catch (DataAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public T findById(String className,Serializable id, boolean lock) {
		if (lock)
			return (T) hibernateTemplate.load(getPersistentClass(), id,
					LockMode.UPGRADE);
		else
			return findById(className,id);
	}

	/**
	 * 根据hql进行查询
	 * 
	 * @param 需要执行的hql语句
	 * @return 查询后的List集合(泛型)
	 */
	public List<T> findByHql(String hql) {
		// 采用自带的方法
		return (List<T>)hibernateTemplate.find(hql);
	}

	/**
	 * 根据sql语句进行查询
	 * 
	 * @param 要执行的sql语句
	 * @param 集合的类型所在的类的全名
	 *            ,如java.lang.Integer或com.shu.model.User;
	 * @return
	 */
	public List<T> findBySql(String sql, String fullClassName) {
		try {
			// 得到session对象
			se = hibernateTemplate.getSessionFactory().openSession();
			// 调用session中的查询方法
			return se.createSQLQuery(sql).addEntity(fullClassName).list();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			// 关闭该关闭的
			se.clear();
			se.close();
		}
	}

	/**
	 * 根据一个对象查询该类对象的集合
	 * 
	 * @param 需要查询的一个具体对象类型
	 * @return 查询到的集合(泛型)
	 */
	public List<T> findByHql(Object obj) {
		// 调用自带方法
		return hibernateTemplate.findByExample(obj);
	}

	/**
	 * 带分页查询的hql查询
	 * 
	 * @param hql
	 * @param 本次查询最多需要查询多少条记录
	 * @param 第一条记录的下标
	 * @return
	 */
	public List<T> findByHql(String hql, int maxResult, int firstResult) {
		try {
			// 得到session对象
			se = hibernateTemplate.getSessionFactory().openSession();
			// 得到并返回集合对象
			return se.createQuery(hql).setMaxResults(maxResult)
					.setFirstResult(firstResult).list();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			// 关掉该关闭的
			se.clear();
			se.close();
		}
	}

	/**
	 * 根据实体对象进行分页查询
	 * 
	 * @param obj
	 * @param maxResult
	 * @param firstResult
	 * @return
	 */
	public List<T> findByHql(Object obj, int maxResult, int firstResult) {
		// 调用自带方法
		return hibernateTemplate.findByExample(obj, firstResult, maxResult);
	}

	/**
	 * 带分页查询的sql语句查询
	 * 
	 * @param sql
	 * @param maxResult
	 * @param firstResult
	 * @return
	 */
	public List<T> findBySql(String sql, int maxResult, int firstResult) {
		try {
			// 得到session对象
			se = hibernateTemplate.getSessionFactory().openSession();
			// 得到并返回集合
			return se.createSQLQuery(sql).setMaxResults(maxResult)
					.setFirstResult(firstResult).list();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			// 关闭该关闭的
			se.clear();
			se.close();
		}
	}

	/**
	 * 根据hql查询单个对象
	 * 
	 * @param hql
	 * @return
	 */
	public T findSingleHql(String hql) {
		// 调用的方法
		List<T> list = findByHql(hql);
		// 判断是否有值
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	/**
	 * 根据sql查询单个对象
	 * 
	 * @param sql
	 * @return
	 */
	public T findSingleSql(String sql, String fullClassName) {
		// 调用的方法
		List<T> list = findBySql(sql, fullClassName);
		// 判断是否有值
		if (list != null && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
	
	public List<T> findAll(String className) {
		 //TODO ..
		 
			System.out.println("查找所有 ["+className+"] 对象。");
			
	        StringBuffer sb = new StringBuffer();  
	        sb.append("from ");  
	        sb.append(className);  
	        List<T> list = (List<T>)hibernateTemplate.find(sb.toString());
		return list;
	}


	/**
	 * 根据不同条件查询对象，并返回list
	 */
	public List<T> findByCriteria(Criterion... criterions) {
		DetachedCriteria crit = DetachedCriteria.forClass(getPersistentClass());
		for (Criterion c : criterions) {
			crit.add(c);
		}
		return hibernateTemplate.findByCriteria(crit);
	}

	/**
	 * 根据不同条件查询对象，并返回list
	 * 添加了排序功能
	 */

	public List<T> findByCriteria(Order order, Criterion... criterions) {
		DetachedCriteria crit = DetachedCriteria.forClass(getPersistentClass());
		for (Criterion c : criterions) {
			crit.add(c);
		}
		if (order != null)
			crit.addOrder(order);
		return hibernateTemplate.findByCriteria(crit);
	}

	/**
	 * 根据不同条件查询对象，并返回list
	 * 添加了排序功能
	 * 带分页功能
	 */
	public List<T> findByCriteria(int firstResult, int rowCount, Order order,
			Criterion... criterions) {
		DetachedCriteria crit = DetachedCriteria.forClass(getPersistentClass());
		for (Criterion c : criterions) {
			crit.add(c);
		}
		se = hibernateTemplate.getSessionFactory().openSession();
		crit.getExecutableCriteria(se).setMaxResults(rowCount);
		crit.getExecutableCriteria(se).setFirstResult(firstResult);
		if (order != null)
			crit.addOrder(order);
		return hibernateTemplate.findByCriteria(crit);
	}

	/**
	 * 采用hql语句进行删除,修改操作
	 * 
	 * @param hql
	 * @return
	 */
	public boolean updateByHql(String hql) {
		try {
			// 得到session对象
			se = hibernateTemplate.getSessionFactory().openSession();
			// 开启事物
			se.beginTransaction();
			// 执行hql查询并判断是否操作成功(这里有个小小自我矛盾:0行受影响暂且归为修改失败)
			if (se.createQuery(hql).executeUpdate() > 0) {
				// 成功操作后则提交事物
				se.getTransaction().commit();
				return true;
			}
			// 回滚
			// se.getTransaction().rollback();
			return false;
		} catch (Exception e) {
			// 报错则回滚事物
			se.getTransaction().rollback();
			return false;
		} finally {
			se.clear();
			se.close();
		}
	}


	/**
	 * 根据sql语句进行修改,删除操作
	 * 
	 * @param sql
	 * @return
	 */
	public boolean updateBySql(String sql) {
		try {
			// 得到session对象
			se = hibernateTemplate.getSessionFactory().openSession();
			// 开始事务处理
			se.beginTransaction();
			if (se.createSQLQuery(sql).executeUpdate() > 0) {
				se.getTransaction().commit();
				return true;
			}
			// 回滚
			// se.getTransaction().rollback();
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 根据hql进行添加操作
	 * 
	 * @param hql
	 * @return
	 */
	public boolean addByHql(String hql) {
		try {
			se = hibernateTemplate.getSessionFactory().openSession();
			// 开启事物
			se.beginTransaction();
			// 调用save方法
			se.save(hql);
			// 提交事物
			se.getTransaction().commit();
			return true;
		} catch (Exception e) {
			// 回滚事物
			se.getTransaction().rollback();
			return false;
		} finally {
			se.clear();
			se.close();
		}
	}

	/**
	 * 根据实体进行添加
	 * 
	 * @param obj
	 * @return
	 */
	public T save(T obj) {
		try {
			// 执行自带的保存方法
			hibernateTemplate.saveOrUpdate(obj);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据sql语句来添加
	 * 
	 * @param sql
	 * @return
	 */
	public boolean addBySql(String sql) {
		try {
			se = hibernateTemplate.getSessionFactory().openSession();
			// 开启事务
			se.beginTransaction();
			// 执行添加操作
			se.save(sql);
			// 提交并返回true
			se.getTransaction().commit();
			return true;
		} catch (Exception e) {
			// 回滚并提示操作失败
			se.getTransaction().rollback();
			return false;
		} finally {
			se.clear();
			se.close();
		}
	}

	@Override
	public void delete(T object) {
		try {
			hibernateTemplate.delete(object);
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public List<T> findByProperty(String className,String property, Object value) {
		// TODO Auto-generated method stub
	        StringBuffer sb = new StringBuffer(100);  
	        sb.append("from ");  
	        sb.append(className);  
	        sb.append(" as a where a.");  
	        sb.append(property);  
	        sb.append("=?");  
	        List<T> list = hibernateTemplate.find(sb.toString(), value);
		return list;
	}

	@Override
	public T findSingleByProperty(String className,String property, Object value) {
        StringBuffer sb = new StringBuffer(100);  
        sb.append("from ");  
        sb.append(className);  
        sb.append(" as a where a.");  
        sb.append(property);  
        sb.append("=?");  
        hibernateTemplate.setMaxResults(1);
        List<T> list = hibernateTemplate.find(sb.toString(), value);
        
		return list.size() > 0 ? list.get(0) : null;
	}

}
